<?php
class Order
{
	/*
	 * TODO
	 * => Modification du statut				:	
	 * => Boissons
	 */
	
	/*
	 * Order status sequence :
	 * Create order
	 */
	
	// Attributs...
	private $orderPrice 		= 0;
	private $orderId;
	private $orderPizzas 		= array();
	private $orderBeverages 	= array();
	private $orderdate;
	private $orderStatus;
	private $clientEmail;
	
	public static $statuts = array(
			'Commandee',
			'En preparation',
			'En livraison',
			'Livree'
			);
	
	// Creates a new, empty order
	public function __construct($clientEmail = null) {
		if($clientEmail != null)
			$this->clientEmail = $clientEmail;
	}
	
	public static function getOrdersForClient($clientEmail)
	{
		$oArray = array();
		
		$query = "SELECT order_id FROM ORDER WHERE client_email ='".$clientEmail."'";
		$stmt = DbConnector::get()->query($query);
		
		$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
		
		foreach($res as $id)
		{
			$oArray[] = getById($id);
		}
		return $oArray;
	}
	
	public static function getById($id)
	{
		$order  = new Order();
		
		// Gets the main order
		$query = "SELECT order_id, client_email, order_date, order_status, 
       order_price
  FROM \"order\" WHERE order_id = '".$id."'";
		
		$stmt = DbConnector::get()->query($query);
		if(!$stmt) throw new Exception("No results.");
		
		$res = $stmt->fetch(PDO::FETCH_ASSOC);
		
		$order->clientEmail = $res['client_email'];
		$order->orderId = $res['order_id'];
		$order->orderPrice = $res['order_price'];
		$order->orderDate = $res['order_date'];
		//$order->orderDate = $res['order_date'];
		$order->orderStatus = $res['order_status'];
		
		// Get pizzas...
		$query = "SELECT pizza_id, pizza_size, pizza_qty
  					FROM order_pizza WHERE order_id ='".$id."'";
		$stmt = DbConnector::get()->query($query);
		
		$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
		
		foreach ($res as $row)
		{
			$order->orderPizzas[] = array(  'id'	=> $row['pizza_id'],
											'qty'	=> $row['pizza_qty'],
											'size'	=> $row['pizza_size']									
										);
		}
		
		// Get beverages...
		$query = "SELECT order_id, boisson_id, boisson_qty
					  FROM order_boisson
							 WHERE order_id ='".$id."'";
		$stmt = DbConnector::get()->query($query);
		
		$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
		
		foreach ($res as $row)
		{
			$order->orderBoissons[] = array('boisson_id'	=> $row['boisson_id'],
										  'boisson_qty'	=> $row['boisson_qty']
			);
		}
		
		return $order;
	}
	// Changes the order status
	public function setStatus($status)
	{
		$query = "UPDATE \"order\"
		SET 		order_status='".$status."'
		WHERE order_id='".$this->orderId."'";
		
		if(!DbConnector::get()->exec($query)) throw new Exception('Bad order status or ID');
		$this->orderStatus = $status;
	}
	
	public function nextStatus()
	{
		switch ($this->orderStatus)
		{
			case 'Commandee':
				$this->setStatus('En preparation');
			break;
				
			case 'En preparation':
				$this->setStatus('En livraison');
				break;
			
			case 'En livraison':
				$this->setStatus('Livree');
				break;
		}
	}
	
	// Get all active orders
	public static function getActive()
	{
		$oArray = array();
		$query = "SELECT order_id FROM \"order\" WHERE order_status IN ('Commandee', 'En preparation')";
		$stmt = DbConnector::get()->query($query);
		if(!$stmt) throw new Exception('Erreur lors de la requête...');
		$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
		foreach($res as $row)
		{
			$oArray[] = Order::getById($row['order_id']);
		}
		return $oArray;
	}
	
	// Adds a pizza to the order
	public function addPizza($pid, $size, $qty)
	{
		$count=count($this->orderPizzas);
		$trouve=false;
		for($i=0;$i<$count;$i++){
			if($this->orderPizzas[$i]['id']==$pid){
				$this->orderPizzas[$i]['qty']=$this->orderPizzas[$i]['qty']+$qty;
				$trouve=true;
			}
		}
		if($trouve!=true){
			$tmp = array(
					'id' => $pid,
					'size' => $size,
					'qty' => $qty 
					);
			array_push($this->orderPizzas, $tmp);
		}
	}
	
	public function addBeverage($bid, $qty)
	{
		$tmp = array (
				'boisson_id' => $bid,
				'boisson_qty' => $qty
				);
		array_push($this->orderBeverages, $tmp);
	}
	
	// Saves a newly created order
	public function save()
	{
		// Gets the timestamp
		$timestamp = time();
		
		// Doesn't work if...
		// Timestamp and client email not set
		if(!isset($timestamp) && !isset($this->clientEmail))
			die('Error : client email not set');
		
		else if(empty($this->orderBeverages) && empty($this->orderPizzas))
			die ('Error : nothing was ordered.');
		
		else
		{
			// Calculate price
			
			// Insert new order with price.
			$insQuery = 
			"INSERT INTO \"order\" (client_email, order_date, order_service_date, order_price)
    		VALUES ('$this->clientEmail', '".date('c', $timestamp)."', '".date('c', $timestamp+1800)."', $this->orderPrice);"; 
			$dbc = DbConnector::get();
			$stmt = $dbc->prepare($insQuery);
			if(!$stmt->execute())
			{
				Order::cleanup($id);
				throw new Exception ("Error while inserting order : ".$insQuery);
			}
			// Get inserted ID value...
			$getQuery = "SELECT order_id FROM \"order\" WHERE client_email = '".$this->clientEmail."' AND order_date = '".date('c', $timestamp)."';";
			$dbc->prepare($getQuery);
			$stmt = $dbc->prepare($getQuery);
			$stmt->execute();
			$result = $stmt->fetch(PDO::FETCH_ASSOC);
			
			if(!isset($result)) 
			{
				Order::cleanup($id);
				throw new Exception("Error : could not determine order status");
			}
			
			// We got the ID
			$id = $result['order_id'];
			
			// Pizza insertion to the order
			if(!empty($this->orderPizzas))
			{
				$pizzQuery = "INSERT INTO order_pizza (order_id, pizza_id, pizza_size, pizza_qty) ";
				foreach($this->orderPizzas as $cmdZap)
				{
					// Adds pizza order to insert
					// If it doesn't contain VALUES, it's the first one
					if(!preg_match('/VALUES/', $pizzQuery)) {
						$pizzQuery = $pizzQuery." VALUES ('".$id."', '".$cmdZap['id']."', '".$cmdZap['size']."', '".$cmdZap['qty']."') ";
					}
					// Next value
					else {
						$pizzQuery = $pizzQuery.", ('".$id."', '".$cmdZap['id']."', '".$cmdZap['size']."', '".$cmdZap['qty']."') ";
					}
				}
				// Actually insert...
				$stmt = $dbc->prepare($pizzQuery);
				if(!$stmt->execute())
				{
					Order::cleanup($id);
					throw new Exception('Could not add pizzas to the order. Nope. Could not, query failed : '.$pizzQuery);
				}
			}
			
			// A éventuellement supprimer si non-fonctionnel
			// Add beverages to the order
			if(!empty($this->orderBeverages))
			{
				$bevQuery = "INSERT INTO order_boisson(order_id, boisson_id, boisson_qty) ";
				foreach($this->orderBeverages as $cmdBev)
				{
					if(!preg_match('/VALUES/', $bevQuery))
					{
						$bevQuery = $bevQuery. " VALUES ('".$id."', '".$cmdBev['boisson_id']."', '".$cmdBev['boisson_qty']."')";
					}
					else
					{
						$bevQuery = $bevQuery. ", ('".$id."', '".$cmdBev['boisson_id']."', '".$cmdBev['boisson_qty']."')";
					}
					$stmt = $dbc->prepare($bevQuery);
					if(!$stmt->execute)
					{
						Order::cleanup($id);
						throw new Exception('Could not add pizzas to the order. Nope. Could not, query failed : '.$bevQuery);
					}
				}
			}
			
			
			// Update price...
			$query = "UPDATE \"order\"
			SET order_price =
			(SELECT SUM(PRIX) FROM (
					(SELECT SUM(PIZZA_PRICE * PIZZA_QTY) AS PRIX
							FROM PIZZA NATURAL JOIN ORDER_PIZZA
							WHERE ORDER_ID = '".$id."'
							GROUP BY ORDER_ID ) UNION
				 (SELECT SUM(BOISSON_PRIX * BOISSON_QTY) AS PRIX
				 		FROM BOISSONS NATURAL JOIN ORDER_BOISSON
				 		WHERE ORDER_ID = '".$id."'
				 		GROUP BY ORDER_ID)
			) a)
			WHERE ORDER_ID = '".$id."'";
			
			// Get price
			
			$stmt = DbConnector::get()->prepare($query);
			if(!$stmt->execute())
			{
				Order::cleanup($id);
				throw new Exception('Could not update price, deleting order...');
			}
			
			// Done. Add payment here.
		}
	}
	public function getXML($isAdmin){
		if($isAdmin!=true){
			$xml = new DOMDocument();
			$xml->formatOutput = true;
			$panierPizza = $xml->createElement('panierpizzas');
			$panierPizza->setAttribute('idCommande', $this->clientEmail);
			$panierPizzaNode = $xml->appendChild($panierPizza);
			$count=count($this->orderPizzas);
			for($i=0;$i<$count;$i++){
				$pizzaNode=$panierPizzaNode->appendChild(new DOMElement('commandepizza',' '));
				$pizzaNode->setAttribute('idpizza',$this->orderPizzas[$i]['id']);
				$pizzaNode->setAttribute('name',Pizza::getNomByID($this->orderPizzas[$i]['id']));
				$pizzaNode->setAttribute('size', $this->orderPizzas[$i]['size']);
				$pizzaNode->setAttribute('qty',  $this->orderPizzas[$i]['qty']);
				$pizzaNode->setAttribute('price',Pizza::getPrixByID($this->orderPizzas[$i]['id'])*$this->orderPizzas[$i]['qty']);
			}
			return $xml->getElementsByTagName('panierpizzas')->item(0);
		}else{
			$xml = new DOMDocument();
			$xml->formatOutput = true;
			$panierPizza = $xml->createElement('panierpizzas');
			$panierPizza->setAttribute('dateCommande', $this->orderdate);
			$panierPizza->setAttribute('idCommande', $this->orderId);
			$panierPizza->setAttribute('idClient', $this->clientEmail);
			$panierPizza->setAttribute('prix', $this->orderPrice);
			$panierPizza->setAttribute('status', $this->orderStatus);
			$panierPizzaNode = $xml->appendChild($panierPizza);
			$count=count($this->orderPizzas);
			for($i=0;$i<$count;$i++){
				$pizzaNode=$panierPizzaNode->appendChild(new DOMElement('commandepizza',' '));
				$pizzaNode->setAttribute('idpizza',$this->orderPizzas[$i]['id']);
				$pizzaNode->setAttribute('name',Pizza::getNomByID($this->orderPizzas[$i]['id']));
				$pizzaNode->setAttribute('size', $this->orderPizzas[$i]['size']);
				$pizzaNode->setAttribute('qty',  $this->orderPizzas[$i]['qty']);
				$pizzaNode->setAttribute('price',Pizza::getPrixByID($this->orderPizzas[$i]['id'])*$this->orderPizzas[$i]['qty']);
			}
			return $xml->getElementsByTagName('panierpizzas')->item(0);
		}
	}
	
	// Cleans up the 
	public static function cleanup($id)
	{
		$query = "DELETE FROM order_pizza WHERE order_id ='".$id."'";
		DbConnector::get()->exec($query);
		$query = "DELETE FROM order_boissons WHERE ORDER_ID ='".$id."'";
		DbConnector::get()->exec($query);
		$query = "DELETE FROM \"order\" WHERE ORDER_ID ='".$id."'";
		DbConnector::get()->exec($query);
	}
}